Skip to content

fix(small-fixes): close 4 audit findings (0.8.5)#36

Merged
lesnik512 merged 7 commits into
mainfrom
fix/small-mop-up
Jun 8, 2026
Merged

fix(small-fixes): close 4 audit findings (0.8.5)#36
lesnik512 merged 7 commits into
mainfrom
fix/small-mop-up

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Summary

Closes 4 of the remaining audit findings — two Lows in production code, two Nits in docs/tests. See planning/specs/2026-06-08-small-fixes-mop-up-design.md for the design and planning/releases/0.8.5.md for the user-facing release notes.

What changes

  • chain.py TYPE_CHECKING block dropped. typing.get_type_hints(compose_async) and typing.get_type_hints(compose) now resolve cleanly.
  • pydantic.py TypeAdapter import is unconditional. Eliminates the NameError window on module-reload with the install flag patched off.
  • LoggingMiddleware docs example uses logging instead of print(). Matches CLAUDE.md's "no print()" invariant.
  • Public-API test asserts set equality against __all__. Catches bogus entries the old subtraction missed.

Audit findings closed

# Severity File:line Closed by
1 Low middleware/chain.py:9-10 hoist Middleware/AsyncMiddleware imports
2 Low decoders/pydantic.py:15-16, 27, 43 unconditional TypeAdapter import
3 Nit docs/middleware.md:156-161 logging-based example
4 Nit tests/test_public_api.py:69-71 symmetric expected == set(__all__)

Test plan

  • Two new tests pin typing.get_type_hints resolution for both compose_async and compose.
  • Existing pydantic-missing tests continue to pass (the flag-patch path doesn't depend on TypeAdapter being conditionally bound).
  • Existing optional-extras isolation tests continue to pass — import httpware does not load pydantic.
  • Full suite + lint green after each commit.

Release

Tag 0.8.5 from the merge SHA after this PR lands.

🤖 Generated with Claude Code

lesnik512 and others added 7 commits June 8, 2026 14:30
Bundles chain.py TYPE_CHECKING fix, pydantic.py TypeAdapter NameError
window fix, LoggingMiddleware docs print() replacement, and symmetric
test_expected_exports assertion. All small, all unrelated, batched to
avoid release churn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each fix is TDD where applicable. T1 (chain.py) has two failing tests
pinning typing.get_type_hints resolution. T2 (pydantic.py) is a contract
narrowing verified by existing tests. T3 (LoggingMiddleware docs) is
docs-only. T4 (public-api test) is a test-quality change. T5 = release
notes + PR opening.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…KING

compose_async and compose used string annotations referencing
AsyncMiddleware / Middleware imported only under `if typing.TYPE_CHECKING:`.
Calling typing.get_type_hints(compose_async) at runtime raised
`NameError: name 'AsyncMiddleware' is not defined`. The TYPE_CHECKING
guard also violates the project's typing-import-style memory rule.

Drop the guard, import the protocols unconditionally at module top, and
unquote the string annotations. httpware.middleware.__init__ does not
import chain.py back, so no circular import.

Tests pin typing.get_type_hints(compose_async) and typing.get_type_hints(
compose) resolve without NameError.

Closes audit Low finding (chain.py:9-10) from
planning/audit/2026-06-07-deep-audit.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… window

_get_adapter and the TypeError fallback inside PydanticDecoder.decode both
referenced TypeAdapter as a bare name. The name was bound only under
`if import_checker.is_pydantic_installed:`. If a test reloaded the module
with the flag patched to False, TypeAdapter was undefined and subsequent
calls raised NameError instead of the documented ImportError.

Hoist `from pydantic import TypeAdapter` unconditionally. The module is
gated upstream by client.py:_default_pydantic_decoder(), which raises
ImportError before this module is loaded when pydantic is absent — there
is no real-world path that loads pydantic.py without pydantic available.

Update the module docstring to reflect the new contract.

Closes audit Low finding (pydantic.py:15-16, 27, 43) from
planning/audit/2026-06-07-deep-audit.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The example previously used `print(...)` to demonstrate a middleware that
records inbound/outbound traffic. CLAUDE.md lists "No print()" as a
non-negotiable architecture invariant, so the doc example would fail CI
in a user's own project if they followed the project's conventions.

Rewrite with a module-level `_LOGGER = logging.getLogger("myapp.logging_middleware")`
and `_LOGGER.info(...)` calls, matching the existing RequestIdMiddleware
example's style further down the same file.

Closes audit Nit finding (docs/middleware.md:156-161) from
planning/audit/2026-06-07-deep-audit.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
test_expected_exports used `missing = expected - set(__all__)` so it
caught symbols missing from __all__ but not the reverse — symbols added
to __all__ that aren't in the expected set slipped through (the companion
test_all_exports_resolve catches symbols in __all__ that don't exist at
all; the gap was real symbols accidentally added to __all__).

Switch to `assert expected == set(__all__)` with a multi-line message
that names both directions, so future test failures pinpoint which side
drifted.

Closes audit Nit finding (test_public_api.py:69-71) from
planning/audit/2026-06-07-deep-audit.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four small unrelated fixes in one patch. chain.py get_type_hints
resolves; pydantic.py NameError window eliminated; LoggingMiddleware
docs example uses logging; public-API test catches bogus __all__ entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lesnik512 lesnik512 self-assigned this Jun 8, 2026
@lesnik512 lesnik512 merged commit a47e2be into main Jun 8, 2026
5 checks passed
@lesnik512 lesnik512 deleted the fix/small-mop-up branch June 8, 2026 12:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant